import requests
from bs4 import BeautifulSoup
import re
import pandas as pd

# 参考网上的代码自己改的一个爬虫，主要为了学习练手bs4，开始时间2020.9.4，抽空写点
# 房天下居然只有首页反爬机制，还是最简单的header，换成新房页面就没有了，笑死我了
URL = 'https://meishan.newhouse.fang.com/house/s'
HTML = requests.get(URL)  # 获取房天下眉山市新房的html
SOUP = BeautifulSoup(HTML.content, 'html.parser', from_encoding='gb18030')  # 读取html文档，解析模式，编码模式
pages = SOUP.select('.clearfix .fr a')  # 选择页码超链接的类名,组合选择可类名、id名、标签名，集合由大到小排列
page_num = len(pages) - 1  # 减去尾页就是当前页数
names_list = []  # 小区名字列表
addresses_list = []  # 地址列表
all_type_list = []  # 类型列表
all_money_list = []  # 价格列表
all_area_list = []  # 地区列表
url_demo = 'http://meishan.newhouse.fang.com/house/s/b9{}'  # 页码超链接
head = { \
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36', \
    'refer': 'https://meishan.newhouse.fang.com/house/s/b91/?ctm=1.meishan.xf_search.page.1'}  # 破解反扒机制，伪装成谷歌浏览器访问，并伪造跳转页面
# 遍历所有页
for i in range(1, len(pages)):
    url = url_demo.format(i)  # 用字符串的format函数将页码完善
    html = requests.get(url, headers=head)  # 获取当前页的html内容
    soup = BeautifulSoup(html.content, 'html.parser', from_encoding='gb18030')  # 读取html文档，解析模式，编码模式
    names = soup.select('.nlc_details .nlcd_name a')  # 选中所有小区名
    for name in names:
        names_list.append(name.text.strip())
    addresses = soup.select('.address a')  # 选中所有地址名
    for address in addresses:
        address_detail = re.findall(r'".+"', str(re.findall(r'title=".+"', str(address))))[0]  # 匹配title=开头的字符串，即地址名
        # 筛选出地区不明的小区
        try:
            area = address.text.replace('\r', '').replace('\n', '').replace('\t', '')[ \
                   address.text.replace('\r', '').replace('\n', '').replace('\t', '').index('['): \
                   address.text.replace('\r', '').replace('\n', '').replace('\t', '').index(']') + 1]
        except:
            area = '[地区不明]'
        all_area_list.append(area)
        addresses_list.append(address_detail.strip('"'))
    all_type = soup.findAll(name="span", \
                            attrs={ \
                                "class": re.compile(r"forSale|inSale|outSale|zusale|zushou")})  # 匹配span标签中所有新房状态,类名为状态
    for type in all_type:
        all_type_list.append(type.text)
    all_money = soup.findAll(name="div", attrs={"class": re.compile(r"nhouse_price|kanesf")})  # 匹配div标签中类名为房价和看二手房，提取价格
    # 提取价格数字
    for money in all_money:
        del_money = money.text.strip().replace('\r', '').replace('\n', '').replace('\t', '')  # 处理空格
        if len(re.findall(r'\d', del_money)) == 0:
            if len(re.findall(r'价格待定', del_money)) == 0:
                all_money_list.append(re.findall(r'新房已售完', del_money)[0])
            else:
                all_money_list.append(re.findall(r'价格待定', del_money)[0])
        else:
            all_money_list.append(int(re.findall(r'\d+', del_money)[0]))
all_message = []
for m in range(0, len(names_list)):
    message = [names_list[m], addresses_list[m], all_area_list[m], all_type_list[m], all_money_list[m]]
    all_message.append(message)
df = pd.DataFrame(all_message, columns=['楼盘名', '地址', '区县', '状态', '价格'])
df.to_excel(r'C:\Users\liutong\Desktop\meishan.xlsx', index=False)
# print(df)
